package pp.infrastructure.mysql.mapper.user;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import pp.infrastructure.exception.PPException;
import pp.infrastructure.exception.PPExceptionInfo;

import java.util.List;

@Repository
@Slf4j
public class UserWriter {

    @Autowired
    private UserMapper mapper;

    public boolean insert(UserDO userDO) {
        // 参数检查
        if(userDO == null || userDO.getTelephone() == null || userDO.getAccount() == null) {
            log.error("{}.{} --> {};", this.getClass().getName(), new Object(){}.getClass().getEnclosingMethod().getName()
                    , "插入 User 表，参数无效; 执行参数: userDO = " + JSON.toJSONString(userDO));
            throw new PPException(PPExceptionInfo.GENERIC_SYSTEM_INNER_PARAM_INVALID);
        }
        // 检查用户 account 是否已经存在
        log.info("-----------------------------\n");
        LambdaQueryWrapper<UserDO> lqw = new LambdaQueryWrapper<>();
        lqw.eq(UserDO::getAccount, userDO.getAccount());
        List<UserDO> checkRecord = mapper.selectList(lqw);
        log.info("************************\n");
        if(!checkRecord.isEmpty()) {
            log.error("{}.{} --> {};", this.getClass().getName(), new Object(){}.getClass().getEnclosingMethod().getName()
                    , "插入 User 表，待插入记录的 id 或 account 已存在，待插入记录 = " + JSON.toJSONString(userDO) + "; 已存在的记录 = " + JSON.toJSONString(checkRecord));
            throw new PPException(PPExceptionInfo.GENERIC_SYSTEM_INNER_PARAM_INVALID);
        }
        // 检查结果
        if(!mapper.register(userDO)) {
            log.error("{}.{} --> {};", this.getClass().getName(), new Object(){}.getClass().getEnclosingMethod().getName()
                    , "插入 User 表，影响行数与预期不符，期望行数 = 1，实际行数 = " + "; 执行参数: userDO = " + JSON.toJSONString(userDO));
            throw new PPException(PPExceptionInfo.GENERIC_SYSTEM_FAIL);
        }
        return true;
    }

    public boolean updateById(UserDO userDO) {
        // 参数检查
        if(userDO == null || userDO.getId() == null || userDO.getAccount() == null || userDO.getUserType() == null) {
            log.error("{}.{} --> {};", this.getClass().getName(), new Object(){}.getClass().getEnclosingMethod().getName()
                    , "更新 User 表记录，参数无效; 执行参数: userDO = " + JSON.toJSONString(userDO));
            throw new PPException(PPExceptionInfo.GENERIC_SYSTEM_INNER_PARAM_INVALID);
        }
        // 额外检查，注意，更新时保证 id 和 account 不可变
        UserDO old = mapper.selectById(userDO.getId());
        if(old == null) {
            log.error("{}.{} --> {};", this.getClass().getName(), new Object(){}.getClass().getEnclosingMethod().getName()
                    , "更新 User 表记录，待更新的记录不存在; 执行参数: userDO = " + JSON.toJSONString(userDO));
            throw new PPException(PPExceptionInfo.GENERIC_SYSTEM_MYSQL_RECORD_NOT_EXIST);
        }
        if(!old.getId().equals(userDO.getId()) || !old.getAccount().equals(userDO.getAccount())) {
            log.error("{}.{} --> {};", this.getClass().getName(), new Object(){}.getClass().getEnclosingMethod().getName()
                    , "更新 User 表记录，User 表的 id 与 account 字段不可更新，老记录 = " + JSON.toJSONString(old) + "; 执行参数: userDO = " + JSON.toJSONString(userDO));
            throw new PPException(PPExceptionInfo.GENERIC_SYSTEM_INNER_PARAM_INVALID);
        }
        // 执行
        int var = mapper.updateById(userDO);
        // 检查结果
        if(var != 1) {
            log.error("{}.{} --> {};", this.getClass().getName(), new Object(){}.getClass().getEnclosingMethod().getName()
                    , "更新 User 表记录，影响行数与预期不符，期望行数 = 1，实际行数 = " + var + "; 执行参数: userDO = " + JSON.toJSONString(userDO));
            throw new PPException(PPExceptionInfo.GENERIC_SYSTEM_FAIL);
        }
        return true;
    }
}
